package com.yonyou.pmclouds.basecom.conf;

import com.yonyou.pmclouds.basecom.shiro.realm.PMCloudsShiroRealm;
import com.yonyou.pmclouds.basecom.shiro.realm.PMFormAuthenticationFilter;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.mgt.WebSecurityManager;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
@ConditionalOnProperty(prefix = "pmc", name = "perm", havingValue = "true", matchIfMissing = true)
public class PMShiroWebConfiguration {
    @Bean
    @Order(FilterLevelConst.LEVEL_SECOND)
    public ShiroFilterFactoryBean shiroFilter(SecurityManager manager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        bean.setSecurityManager(manager);

        Map<String, Filter> filters = new LinkedHashMap<>();
        filters.put("authc", new PMFormAuthenticationFilter());
        filters.put("perms", new PermissionsAuthorizationFilter());
        bean.setFilters(filters);

        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/mobile/**", "anon");
        filterChainDefinitionMap.put("/rest/**", "anon");
        filterChainDefinitionMap.put("/outter/**", "anon");
        filterChainDefinitionMap.put("/**", "authc");
        bean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return bean;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor shiroAdivsor(SecurityManager manager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(manager);
        return advisor;
    }

    @Bean
    public WebSecurityManager securityManager(AuthorizingRealm realm, CacheManager cacheManager) {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setRealm(realm);
        manager.setCacheManager(cacheManager);
        return manager;
    }

    @Bean
    public PMCloudsShiroRealm pmCloudsShiroRealm(CacheManager cacheManager) {
        PMCloudsShiroRealm pmCloudsShiroRealm = new PMCloudsShiroRealm();
        pmCloudsShiroRealm.setCacheManager(cacheManager);
        return pmCloudsShiroRealm;
    }

    @Bean
    public CacheManager cacheManager() {
        return new MemoryConstrainedCacheManager();
    }

    @Bean
    public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }


}
